package com.flexdms.i18n;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.AjaxBehaviorEvent;
import javax.faces.model.SelectItem;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;
import javax.transaction.UserTransaction;

import net.sf.ehcache.Ehcache;

import org.omnifaces.util.Faces;

@ViewScoped
@Named("i18NMsg")
public class I18NMsgEditor implements Serializable
{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	@Inject
	I18NMessage i18nMessage;

	@Resource
	UserTransaction tx;

	List<String> columns;
	String selectedColumn;
	String newColumn;
	String newKey;
	Map<String, String> msgs;
	

	@PostConstruct
	protected void init()
	{

		try
		{
			columns = i18nMessage.getColumns(i18nMessage.initTable());
			columns.add(0, i18nMessage.getDefaultLocale());
			selectedColumn =i18nMessage.getDefaultLocale(); 
			msgs = new TreeMap<String, String>();
			msgs.putAll(i18nMessage.loadMessages(selectedColumn));
			
			Set<String>  lsCodes=new HashSet<String>();
			lsCodes.add(i18nMessage.getDefaultLocale());
			for(String column: columns)
			{
				lsCodes.add(column);
			}
			List<Locale> ls=Arrays.asList(Locale.getAvailableLocales());
			Collections.sort(ls, new Comparator<Locale>() {

				@Override
				public int compare(Locale o1, Locale o2)
				{
					return o1.getDisplayLanguage().compareTo(o2.getDisplayLanguage());
				}
				
			});
			for(Locale l:ls)
			{
				String country=l.getCountry();
				String lcodeString=I18NMessage.localeToString(l);
				if (country!=null && country.length()>0)
				{
					if (!lsCodes.contains(lcodeString))
					{
						lsCodes.add(lcodeString);
						SelectItem item=new SelectItem(lcodeString, l.getDisplayLanguage(i18nMessage.getCurrentLocale())+"("+l.getDisplayCountry(i18nMessage.getCurrentLocale())+")");
						langsItems.add(item);
					}
				} else {
					if (!lsCodes.contains(lcodeString))
					{
						lsCodes.add(lcodeString);
						SelectItem item=new SelectItem(lcodeString, l.getDisplayLanguage(i18nMessage.getCurrentLocale()));
						langsItems.add(item);
					}
				}
			}
		} catch (SQLException e)
		{
			FacesMessage msg = new FacesMessage(e.getMessage());
			msg.setSeverity(FacesMessage.SEVERITY_ERROR);
			FacesContext.getCurrentInstance().addMessage(null, msg);
		}

	}

	public List<String> getColumns()
	{
		return columns;
	}

	public String getSelectedColumn()
	{
		return selectedColumn;
	}

	public void setSelectedColumn(String selectedColumn)
	{
		this.selectedColumn = selectedColumn;
	}

	public String getNewColumn()
	{
		return newColumn;
	}

	public void setNewColumn(String newColumn)
	{
		this.newColumn = newColumn;
	}

	public List<Map.Entry<String, String>> getMsgsEntries()
	{
		List<Map.Entry<String, String>> entries = new ArrayList<Map.Entry<String, String>>(msgs.size());
		entries.addAll(msgs.entrySet());
		return entries;
	}

	public void addColumn(AjaxBehaviorEvent event)
	{
		if (newColumn == null)
		{
			return;
		}
		Locale locale = I18NMessage.stringToLocale(newColumn);
		if (locale.getLanguage().length() == 0)
		{
			FacesMessage msg = new FacesMessage("Bad Locale string");
			msg.setSeverity(FacesMessage.SEVERITY_ERROR);
			FacesContext.getCurrentInstance()
					.addMessage(null, msg);
			return;
		}
		for (String col : columns)
		{
			if (newColumn.equalsIgnoreCase(col))
			{
				FacesMessage msg = new FacesMessage(
						"That locale is already exists");
				msg.setSeverity(FacesMessage.SEVERITY_ERROR);
				FacesContext.getCurrentInstance().addMessage(null,
						msg);
				return;
			}
		}
		try
		{
			tx.begin();
			i18nMessage.addColumn(newColumn);
			columns.add(newColumn);
			newColumn = null;
			tx.commit();
		} catch (Exception e)
		{
			try
			{
				tx.rollback();
			} catch (Exception e1)
			{

			}
			FacesMessage msg = new FacesMessage(e.getMessage());
			msg.setSeverity(FacesMessage.SEVERITY_ERROR);
			FacesContext.getCurrentInstance().addMessage(null,
					msg);
		}

	}

	public void translate(AjaxBehaviorEvent event)
	{
		try
		{
			tx.begin();
			List<String> keysList = new ArrayList<String>();
			for (Map.Entry<String, String> entry : msgs.entrySet())
			{
				if (entry.getValue() == null)
				{
					keysList.add(entry.getKey());
				}
			}
			List<String> resultsList = i18nMessage.getTranslator().translate(
					keysList, I18NMessage.stringToLocale(selectedColumn));
			i18nMessage.updateMsg(keysList, resultsList, selectedColumn);
			msgs.clear();
			msgs.putAll(i18nMessage.loadMessages(selectedColumn));
			tx.commit();
		} catch (Exception e)
		{
			try
			{
				tx.rollback();
			} catch (Exception e1)
			{

			}
			FacesMessage msg = new FacesMessage(e.getMessage());
			msg.setSeverity(FacesMessage.SEVERITY_ERROR);
			FacesContext.getCurrentInstance().addMessage(null, msg);
		}

	}

	public void switchColumn(AjaxBehaviorEvent event)
	{
		try
		{
			msgs.clear();
			msgs.putAll(i18nMessage.loadMessages(selectedColumn));
		} catch (Exception e)
		{
			FacesMessage msg = new FacesMessage(e.getMessage());
			msg.setSeverity(FacesMessage.SEVERITY_ERROR);
			FacesContext.getCurrentInstance().addMessage(null, msg);
		}

	}

	public String getNewKey()
	{
		return newKey;
	}

	public void setNewKey(String newKey)
	{
		this.newKey = newKey;
	}

	public void addNewKey(AjaxBehaviorEvent event)
	{
		try
		{
			tx.begin();

			i18nMessage.insertMsg(newKey, newKey, i18nMessage.getDefaultLocale());
			msgs.put(newKey, newKey);
			i18nMessage.clearCache();
			newKey = null;
			tx.commit();
		} catch (Exception e)
		{
			try
			{
				tx.rollback();
			} catch (Exception e1)
			{

			}
			FacesMessage msg = new FacesMessage(e.getMessage());
			msg.setSeverity(FacesMessage.SEVERITY_ERROR);
			FacesContext.getCurrentInstance().addMessage(null, msg);
		}
	}

	public void editKey(ActionEvent event)
	{
		try
		{
			tx.begin();
			String key = Faces.getRequestParameter("key");
			String value = Faces.getRequestParameter("value");
			i18nMessage.updateMsg(key, value, selectedColumn);
			msgs.put(key, value);
			i18nMessage.clearCache();
			tx.commit();
		} catch (Exception e)
		{
			try
			{
				tx.rollback();
			} catch (Exception e1)
			{

			}
			FacesMessage msg = new FacesMessage(e.getMessage());
			msg.setSeverity(FacesMessage.SEVERITY_ERROR);
			FacesContext.getCurrentInstance().addMessage(null, msg);
		}

	}

	public void deleteKey(String key)
	{
		try
		{
			tx.begin();
			i18nMessage.deleteMsg(key);

			msgs.remove(key);
			i18nMessage.clearCache();
			tx.commit();
		} catch (Exception e)
		{
			try
			{
				tx.rollback();
			} catch (Exception e1)
			{

			}
			FacesMessage msg = new FacesMessage(e.getMessage());
			msg.setSeverity(FacesMessage.SEVERITY_ERROR);
			FacesContext.getCurrentInstance().addMessage(null, msg);
		}
	}
	
	List<SelectItem> langsItems=new ArrayList<SelectItem>();
	public List<SelectItem> getAvailableLangs()
	{
		return langsItems;
	}
	
	public Map<String, String> getTempTranslation()
	{
		Map<String, String> temp=new TreeMap<String, String>();
		DefaultResourceImpl rb=(DefaultResourceImpl) i18nMessage.loadBundle(I18NMessage.stringToLocale(i18nMessage.getDefaultLocale()));
		Ehcache cache=rb.getCache();
		for(Object key: cache.getKeys())
		{
			temp.put((String)key, (String)cache.get(key).getObjectValue());
		}
		return temp;
	}
	public String getTempValue(String key)
	{
		DefaultResourceImpl rb=(DefaultResourceImpl) i18nMessage.loadBundle(I18NMessage.stringToLocale(i18nMessage.getDefaultLocale()));
		return (String) rb.getCache().get(key).getObjectValue();
	}
	public List<?> getTempKeys()
	{
		DefaultResourceImpl rb=(DefaultResourceImpl) i18nMessage.loadBundle(I18NMessage.stringToLocale(i18nMessage.getDefaultLocale()));
		Ehcache cache=rb.getCache();
		return cache.getKeys();
	}
	public void persistTempKey(String key)
	{
	
		try
		{

			tx.begin();
			DefaultResourceImpl rb = (DefaultResourceImpl) i18nMessage
					.loadBundle(I18NMessage.stringToLocale(selectedColumn));
			Ehcache cache = rb.getCache();
			String result = (String) cache.get(key).getObjectValue();
			cache.remove(key);
			i18nMessage.insertMsg(key, result, selectedColumn);

			i18nMessage.clearCache();
			tx.commit();
		} catch (Exception e)
		{
			try
			{
				tx.rollback();
			} catch (Exception e1)
			{

			}
			FacesMessage msg = new FacesMessage(e.getMessage());
			msg.setSeverity(FacesMessage.SEVERITY_ERROR);
			FacesContext.getCurrentInstance().addMessage(null, msg);
		}

	}
	

}
